package com.by.auth;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author wang
 * @version 版本号 ${}
 * @className TokenTemplate
 * @日期 2024/9/6 14:06
 * @since jdk1.8
 */
@Component
public class TokenTemplate {
    /**
     * 密钥
     */
    @Value("${token.secret}")
    String secret; //密钥


    /**
     * token有效时间  单位是s
     */
    @Value("${token.validTime}")
    long validTime;
    
    private final long DEFAULT_TIME=30*60*1000; //默认30分钟有效期
    
    /**
     * 生成token
     *
     * @param payload 用户信息
     * @return token字符串
     */
    public String generateToken(Map payload){
        String token = JWT.create()
                .withHeader(getHeader())
                .withPayload(payload)
                .withExpiresAt(getValidDate()) //给token设置有效期
                .sign(Algorithm.HMAC256(getSecret()));
        return token;
        
    }
    
    /**
     *
     */
    
    public ValidResult validate(String token){
        if (null==token || "".equals(token)){
            return new ValidResult(0,"token为空",null);
        }
        //不为空验证
        DecodedJWT decodedJWT=null;
        
        try {
            decodedJWT=JWT.require(Algorithm.HMAC256(secret))
                    .build()
                    .verify(token);
        }catch (TokenExpiredException e){
            return new ValidResult(0,"token已过期",null);
        }catch (Exception e){
            return new ValidResult(1,"token无效",null);
        }
        //验证通过
        Map<String, Claim> map=decodedJWT.getClaims();
        return new ValidResult(2,"验证成功",convert(map));
        
        
    }
    
    public String refreshToken(String token){
        //验证token
        ValidResult result=validate(token);
        if (result.getCode()==1){//token无效
            return null;
        }else if (result.getCode()==0){
            //说明过期
            DecodedJWT decodedJWT=JWT.decode(token);
            //获取用户信息
            Map<String,Claim> map=decodedJWT.getClaims();
            //生成新的token
            return generateToken(convert(map));
            
        }
        //token正常时刷新
        Map map=result.getUser();
        //生成新的token
        return generateToken(map);
        
    }
    
    
    Map<String,String> convert(Map<String,Claim> map){
        Map<String,String> tmp=new HashMap<>();
        //遍历map
        map.forEach((key,value)->{
            tmp.put(key,value.asString());
        });
        return tmp;
    }
     /*
   获取30s后的日期
    */
    Date getValidDate(){
        long time =System.currentTimeMillis()+getValidTime();
        Date now=new Date(time);
        return now;
    }
    /**
     * 头部
     *
     * @return
     */
    Map getHeader(){
        Map map=new HashMap();
        map.put("type","JWT");
        map.put("alg","HS256");
        return map;
    }
    
    public String getSecret(){
        if (null==secret){
            secret=UUID.randomUUID().toString();//随机产生一个36位字符串
        }
        return secret;
    }
    
    public void setSecret(String secret){
        this.secret=secret;
    }
    
    public long getValidTime(){
        if (validTime==0){
            //初始化
            validTime=DEFAULT_TIME;
        }
        return validTime;
    }
    
    public void setValidTime(long validTime){
        this.validTime=validTime;
    }
}
